package cn.kgc.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.kgc.entity.TccRecord;
import cn.kgc.entity.Users;
import cn.kgc.excpetion.GraceException;
import cn.kgc.grace.result.ResponseStatusEnum;
import cn.kgc.mapper.UsersMapper;
import cn.kgc.service.TccRecordService;
import cn.kgc.service.UsersTccService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

import static cn.kgc.base.SystemConstant.*;

/**
 * @author wangyue
 * @version 1.0
 */
@Service("usersTccService")
@Slf4j
public class UsersTccServiceImpl implements UsersTccService {
    @Resource
    private TccRecordService tccRecordService;
    @Resource
    private UsersMapper usersMapper;

    @Override
    @Transactional
    public Users registerUser(BusinessActionContext actionContext, String mobile) {
        //分支事务id
        String branchId = actionContext.getBranchId()+"";
        //全局事务id
        String xid= actionContext.getXid();
        //1 判断全局事务id和分支事务id是否为null,如果为空抛出异常
        if(StrUtil.isBlank(branchId) || StrUtil.isBlank(xid)){
            log.warn("全局事务id和分支事务id不能为空");
            GraceException.display(ResponseStatusEnum.USER_REGISTER_ERROR);
        }
        //2 当前分支事务中是否已经执行过try操作 (幂等性)
        if(tccRecordService.hasTry(xid,branchId)){
            log.warn("全局事务{}中的分支事务{},已经执行过try操作",xid,branchId);
            GraceException.display(ResponseStatusEnum.USER_REGISTER_ERROR);
        }
        //3 当前分支事务中是否已经执行过cancel操作 (事务悬挂)
        if(tccRecordService.hasCancel(xid,branchId)){
            log.warn("全局事务{}中的分支事务{},已经执行过cancel操作",xid,branchId);
            GraceException.display(ResponseStatusEnum.USER_REGISTER_ERROR);
        }
        //4 执行try操作,向TCCRecord表中插入记录
        Users users=new Users();
        users.setMobile(mobile);
        users.setSex(SEX_SECRET);
        users.setPosition("保密"); //岗位
        users.setRole(ROLE_JOB_SEEKERS);    //角色
        users.setFace("");    //头像为空
        users.setNickname(mobile.substring(5)); //昵称为手机号后6位
        users.setRealName(mobile.substring(5)); //真实名称
        users.setShowWhichName(SHOW_WHICH_NAME_NICK_NAME); //对外展示的名字
        users.setEmail("");//邮箱
        users.setBirthday(new Date());   //生日
        users.setCountry("中国"); //国家
        users.setProvince(""); //省
        users.setCity(""); //市
        users.setDistrict("");//区
        users.setDescription("");  //自我介绍
        users.setStartWorkDate(new Date());//参加工作的时间
        users.setHrInWhichCompanyId("");  //求职者没有绑定公司
        users.setHrSignature("这家伙很懒什么都没有写"); //一句话签名
        users.setHrTags("纯牛马");//个性化签名
        usersMapper.insert(users);  //新增用户信息
        //向tccRecord表中插入一条记录
        TccRecord tccRecord= TccRecord.builder().status((short)1)
                .xid(xid)
                .branchId(branchId)
                .actionName("registerUser")
                .args(
                        JSONUtil.toJsonStr(
                                new Object[]{mobile}
                        )
                ).build();
        tccRecordService.save(tccRecord);
        return users;
    }

    @Override
    public boolean commitRegisterUser(BusinessActionContext actionContext) {
        return true;
    }

    @Override
    public boolean rollbackRegisterUser(BusinessActionContext actionContext) {
        //分支事务id
        String branchId=actionContext.getBranchId()+"";
        //全局事务id
        String xid = actionContext.getXid();
        //1 判断cancel操作是否已经执行过
        if(tccRecordService.hasCancel(xid,branchId)){
            log.warn("全局事务{}中的分支事务{},已经执行过cancel操作",xid,branchId);
            return true;
        }
        String mobile= (String) actionContext.getActionContext("mobile");
        //2 判断是否没有执行过try操作
        if(!tccRecordService.hasTry(xid,branchId)){
            //如果没有执行过try操作,不需要执行cancel操作(防止空回滚)
            log.warn("全局事务{}中的分支事务{},没有执行过try操作",xid,branchId);
            //记录下日志信息
            TccRecord tccRecord = TccRecord.builder()
                    .status((short) 3)
                    .xid(xid)
                    .branchId(branchId)
                    .actionName("rollbackRegisterUser")
                    .args(JSONUtil.toJsonStr(new String[]{mobile}))
                    .build();
            tccRecordService.save(tccRecord);
            return true;
        }
        //3 执行cancel操作,删除用户信息
        usersMapper.delete(new LambdaQueryWrapper<Users>().eq(Users::getMobile,mobile));
        //4 更新TCC_RECORD表中的分支事务的ID状态为CANCEL状态
        LambdaUpdateWrapper<TccRecord>  updateWrapper=new LambdaUpdateWrapper<>();
        updateWrapper.eq(TccRecord::getXid,xid);
        updateWrapper.eq(TccRecord::getBranchId,branchId);
        updateWrapper.set(TccRecord::getStatus,(short)3);
        tccRecordService.update(updateWrapper);
        return true;
    }
}
